<template>
  <!-- 树组件 -->
  <el-popover ref="popover" placement="bottom-start" trigger="manual"
    @show="onShowPopover" @hide="onHidePopover" v-model="visible">
    <el-input slot="reference" ref="input" v-model="labelModel" :readonly="disabled"
      :clearable="clearable" :placeholder="placeholder" class="c-input"
      :style="`width: ${width}px`" :suffix-icon="showStatus|icon_f"
      @click.native="inputClick">
    </el-input>
    <el-scrollbar class="scrollbar">
      <c-tree :treeData="treeData" ref="cTree"
        :isLeaf="isLeaf" :lazy="lazy" :iTop="iTop"
        :isControlFloder="false" @node-click="onClickNode"
        :style="`min-width: ${treeWidth}`" />
    </el-scrollbar>
  </el-popover>
</template>
<script>
export default {
  name: 'cSeleteTree',
  model: { // 设置绑定参数
    prop: 'value',
    event: 'selected'
  },
  props: {
    // 接收绑定参数
    value: String,
    // 显示值
    label: String,
    // 输入框宽度
    width: String,
    // 选项数据
    treeData: {
      type: Array,
      required: true
    },
    // 输入框占位符
    placeholder: {
      type: String,
      default: '请选择'
    },
    // 树节点配置选项
    props: {
      type: Object,
      default: () => ({
        parent: 'pid', value: 'id',
        label: 'name', children: 'children',
        offActive: false, isLeaf: 'leaf'
      })
    },
    lazy: Boolean, // 是否启动-懒加载
    isLeaf: String, // 懒加载字段 - 优先级大于option.isLeaf
    iTop: String, // icon 偏移高度
    disabled: Boolean, // 是否禁止输入
    clearable: Boolean // 清除功能
  },
  data() {
    return {
      // 树状菜单显示状态   菜单宽度
      showStatus: false, treeWidth: 'auto',
      // 输入框显示值          实际请求传值
      labelModel: this.label, valueModel: this.value,
      // 是否打开弹窗
      visible: false
    }
  },
  created() {
    // 获取输入框宽度同步至树状菜单宽度
    this.$nextTick(() => {
      this.treeWidth = `${(this.width || this.$refs.input.$refs.input.clientWidth) - 24}px`
    })
  },
  methods: {
    // 单击节点
    onClickNode(node) {
      const { row, type } = node
      if (type == 'node') {
        this.labelModel = row[this.props.label]
        this.valueModel = row[this.props.value]
        this.onCloseTree()
      } else {
        this.$emit('openTree', node)
      }
    },
    inputClick(e) {
      const disabled = e.target.attributes.disabled
      if (!disabled) {
        this.visible = !this.visible
      }
    },
    // 隐藏树状菜单
    onCloseTree() {
      this.$refs.popover.showPopper = false
    },
    // 显示时触发
    onShowPopover() {
      this.showStatus = true
      // 默认选中
      this.clearActive(this.treeData, this.value)
    },
    // 隐藏时触发
    onHidePopover() {
      this.showStatus = false
      this.clearActive(this.treeData)
      this.$emit('selected', this.valueModel)
    },
    // 清除|选中项
    clearActive(list, id) {
      const child = this.props.children
      let bool = false
      list.forEach((o, i) => {
        if (id != null) { // 选中
          if (o.id == id) {
            o.active = true
            this.$set(list, i, o) // 更新视图
            bool = true
            return
          }
        } else { // 清除
          if (o.active) {
            o.active = false
            this.$set(list, i, o) // 更新视图
            bool = true
            return
          }
        }
        if (o[child] && o[child].length) {
          const res = this.clearActive(o[child], id)
          res && this.$set(list, i, o) // 更新视图
        }
      })
      return bool
    }
  },
  filters: {
    icon_f(val) {
      const end = val ? 'up' : 'down'
      return 'el-icon-arrow-' + end
    }
  }
}
</script>
<style lang="scss" scoped>
.c-input {
  ::v-deep input:read-only:not(:disabled){
    background-color: #F5F7FA;
    border-color: #E4E7ED;
    color: #C0C4CC;
    cursor: pointer;
  }
}
// 滚动条
.scrollbar {
  ::v-deep .el-scrollbar__wrap {
    max-height: 200px; // 最大高度
    padding-bottom: 17px;
    overflow-x: auto; // 隐藏横向滚动栏
  }
}
</style>
